import React, { Component } from 'react';
import Taro from '@tarojs/taro';
import {View, Input, Text} from '@tarojs/components'
import {AtInputNumber, AtTextarea, AtModal} from 'taro-ui'
import {user} from '../../utils/user.service'
import {ScenicGood, AppointmentItem} from '../../utils/server.interface'
import {http} from '../../utils/http'
import {
  APPONINTMENT_GET,
  APPONINTMENT_LIST_GOODS,
  APPONINTMENT_DAYS_INFO,
  APPONINTMENT_GETFEE,
  APPONINTMENT_CREATE_NEW_ORDER,
  TARO_ENV,
  DAY_INFO_LIMIT
} from '../../constants/api'
import Calendar from './appointmentCalendar'
import {vcmonitor} from "../../utils/tools";
import {h5Wx} from "../../utils/h5.service";
import GzhAuth from "../../components/gzh-auth/gzh-auth"
import {payment} from "../../utils/payment.service";
import './order.scss'

interface Product extends ScenicGood {
  selected: boolean
}

interface StateType {
  products: Product[]
  appointment: AppointmentItem | false
  isOpened: boolean
  date: { start: string; end: string; range: string[] }
  num: number
  maxAmount: number
  nights: number
  code: string[]
  name: string
  phone: string
  identity_num: string
  identity:boolean
  loadStatus: string
  remarks: string
  daysInfo: DayInfo[]
  curUuid: string
  totalNum: number
  orderType: number
  dateNum: number
  totalPrice: number
}

interface DayInfo {
  date: string
  price: number
  stock_balance: number
}

export default class Order extends Component {
  state: StateType = {
    products: [],
    identity:false,
    appointment: false,
    isOpened: false,
    date: {start: '', end: '', range: []},
    loadStatus: 'loading',
    num: 1,
    nights: 1,
    maxAmount: 1,
    code: [''],
    name: '',
    phone: '',
    remarks: '',
    daysInfo: [],
    curUuid: '',
    totalNum: 0,
    orderType: 1,
    identity_num: '',
    dateNum: 1,
    totalPrice: 0
  }

  async UNSAFE_componentWillMount() {
    if (process.env.TARO_ENV === 'h5') {
      await h5Wx.getConfig()
    }
    if (process.env.TARO_ENV === "weapp") {
      Taro.hideShareMenu()
    }
    const isLogin = await user.checkLogin()
    if (!isLogin) {
      Taro.showToast({
        title: '你还未登录，请登录',
        icon: 'none',
      })
      const timer = setTimeout(() => {
        clearTimeout(timer)
        user.jumpLogin()
      }, 1500)
      return
    }
  }

  async componentDidShow() {
    vcmonitor(this);
    const isLogin = await user.checkLogin()
    if (!isLogin) {
      return
    }
    const {itemId = '', orderUUID = ''} = Taro.getCurrentInstance().router.params
    if (!itemId) {
      Taro.showToast({title: '参数错误', icon: 'none'})
      const timer = setTimeout(() => {
        clearTimeout(timer)
        Taro.navigateBack()
      }, 1500)
      return
    }
    this.goodId = itemId
    this.orderUUID = orderUUID
    await this.initData()
  }

  goodId = ''
  orderUUID = ''
  btnDisabled = false

  async initData() {
    Taro.showLoading({title: '加载中'})
    const appointment = await http.get<AppointmentItem>(APPONINTMENT_GET, {uuid: this.goodId})
    if (!appointment) {
      const timer = setTimeout(() => {
        Taro.navigateBack()
        clearTimeout(timer)
      }, 1000);
      return false
    }
    if (appointment && appointment.msg && (appointment.msg === '预约已结束' || appointment.msg === '预约未开始')) {
      this.btnDisabled = true
    }
    const productsData = await http.get<Product[]>(APPONINTMENT_LIST_GOODS, {uuid: this.goodId})
    let products: Product[] = []
    if (productsData && productsData.length > 0) {
      products = productsData.map((item, index) => {
        item.selected = index === 0;
        return item
      })
    }
    this.setState({appointment, products, curUuid: products.length > 0 ? products[0].uuid : ''}, async () => {
      if (await this.setDaysInfo()) {
        await this.getFee()
      }
    })
  }

  async setDaysInfo() {
    return new Promise(async (resolve) => {
      let {appointment, curUuid, nights} = this.state
      const now = new Date()
      let nowDate = `${now.getFullYear()}-${(now.getMonth() + 1 < 10 ? '0' + (now.getMonth() + 1) : now.getMonth() + 1)}-${(now.getDate() < 10 ? '0' + now.getDate() : now.getDate())}`
      let daysInfo: DayInfo[] = []
      const daysInfoData = await http.get<DayInfo[]>(APPONINTMENT_DAYS_INFO, {goodsUuid: curUuid})
      if (daysInfoData && daysInfoData.length > 0) {
        daysInfo = daysInfoData
        nowDate = daysInfoData[0].date
      }
      const date = {start: nowDate, end: '', range: []}
      if ((appointment && appointment.continuous_type === 2) || appointment.goods_type === 2) {
        let timestamp = 24 * 60 * 60 * 1000
        if (appointment.late_num) {
          timestamp = timestamp * appointment.late_num
        }
        const nextDate = new Date(new Date(nowDate.replace(/-/g, '\/')).getTime() + timestamp)
        date.end = `${nextDate.getFullYear()}-${(nextDate.getMonth() + 1 < 10 ? '0' + (nextDate.getMonth() + 1) : nextDate.getMonth() + 1)}-${(nextDate.getDate() < 10 ? '0' + nextDate.getDate() : nextDate.getDate())}`
        nights = ((new Date(date.end).getTime() - new Date(nowDate).getTime()) / 86400000)
      }
      this.setState({date, daysInfo, nights}, () => {
        resolve(true)
        this.setState({ loadStatus: 'noMore' })
      })
    });
  }

  selectProduct(uuid) {
    this.setState({loadStatus: 'loading'})
    if (uuid) {
      const products = this.state.products.map(item => {
        item.selected = item.uuid === uuid;
        return item
      })
      this.setState({products, curUuid: uuid}, async () => {
        if (await this.setDaysInfo()) {
          await this.getFee()
          this.setState({loadStatus: 'noMore'})
        }
      })
    }
  }

  orderNumRangeType = true

  calendarConfirm(date: { single: string; type: "single" | 'range'; start: string; end: string; range: string[] }) {
    Taro.showLoading({title: '加载中...'})
    if (date.type === 'single') {
      this.setState({date: {start: date.single}}, async () => {
        await this.getFee()
      })
    }
    if (date.type === 'range') {
      let nights = 1
      if (date.start && date.end) {
        this.orderNumRangeType = true
        let date1
        if (this.state.appointment.late_num) {
          date1 = new Date(new Date(date.end).getTime())
        } else {
          date1 = new Date(new Date(date.end).getTime())
        }
        const y = date1.getFullYear() + '-'
        const m = (date1.getMonth() + 1 < 10 ? '0' + (date1.getMonth() + 1) : date1.getMonth() + 1) + '-'
        const d = (date1.getDate() < 10 ? '0' + date1.getDate() : date1.getDate())
        date.end = y + m + d
        nights = ((new Date(date.end).getTime() - new Date(date.start).getTime()) / 86400000)
      }
      if (date.start && !date.end) {
        this.orderNumRangeType = false
        const date1 = new Date(new Date(date.start).getTime())
        const y = date1.getFullYear() + '-'
        const m = (date1.getMonth() + 1 < 10 ? '0' + (date1.getMonth() + 1) : date1.getMonth() + 1) + '-'
        const d = (date1.getDate() < 10 ? '0' + date1.getDate() : date1.getDate())
        date.end = y + m + d
      }
      this.setState({
        date: {start: date.start, end: date.end, range: date.range},
        nights,
        dateNum: date.range.length + 1
      }, async () => {
        // this.numChange(this.state.dateNum * this.state.num)
        await this.getFee()
      })
    }
  }

  numChange() {
    this.getFee()
  }

  iosScroll() {
    if (TARO_ENV === 'h5') {
      const u = navigator.userAgent
      const isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
      if (isIOS) {
        setTimeout(() => {
          const scrollHeight = document.documentElement.scrollTop || document.body.scrollTop || 0
          window.scrollTo(0, Math.max(scrollHeight - 1, 0))
        }, 200)
      }
    }
  }

  codeInput(index, value) {
    const code = this.state.code
    code[0] = value.detail.value
    this.setState({code})
  }
  // testInput({ detail }, key) {
  //   const { custom_item_detail } = this.state;
  //   custom_item_detail[key] = detail.value;
  //   this.setData(custom_item_detail);
  // }
  // setData(custom_item_detail) {
  //   this.setState({
  //     custom_item_detail
  //   });
  // }
  async getFee() {
    let {curUuid, num, date, appointment} = this.state
    const data = {
      uuid: this.goodId,
      totalNum: num,
      num,
      goodsUuid: curUuid,
    }
    const query = {
      order_uuid: this.orderUUID,
      uuid: this.goodId
    }
    if (appointment.continuous_type === 2 || (appointment.continuous_type === 1 && appointment.goods_type === 2)) {
      data['appointmentDateRange'] = JSON.stringify(date)
      query['appointmentDateRange'] = JSON.stringify(date)
    } else {
      data['appointmentDate'] = date.start
      query['appointmentDate'] = date.start
    }
    query['goods_uuid'] = curUuid
    const ret = await http.get<number>(APPONINTMENT_GETFEE, data)
    if (ret !== false) {
      this.setState({totalPrice: ret})
    }
    if (this.orderUUID) {
      const res = await http.HGet(DAY_INFO_LIMIT, query)
      if (res) {
        const maxAmount = res.data.max_amount
        if (maxAmount === 0) {
          num = 0
        } else if (num > maxAmount) {
          num = 1
        }
        if (res.data.ticket || Taro.getCurrentInstance().router.params.ticket) {
          this.setState({code: [`${res.data.ticket || Taro.getCurrentInstance().router.params.ticket}`]})
        }
        this.setState({maxAmount, num})
      }
    }
    Taro.hideLoading()
  }

  async confirm() {
    const isLogin = await user.checkLogin()
    if (!isLogin) {
      Taro.showToast({
        title: '你还未登录，请登录',
        icon: 'none',
      })
      const timer = setTimeout(() => {
        clearTimeout(timer)
        user.jumpLogin()
      }, 1500)
      return
    }
    const {date, code, name, phone, remarks, curUuid, num, appointment, identity_num,identity} = this.state
    let ret
    code.forEach(item => {
      ret = item;
    })
    if (!ret) {
      Taro.showToast({title: '券码不能为空', icon: 'none'})
      return false
    }
    if (!name || name.length < 2) {
      Taro.showToast({title: '请正确填写姓名', icon: 'none'})
      return false
    }
    if (!(/^1\d{10}$/.test(phone))) {
      Taro.showToast({title: '请正确填写手机号码', icon: 'none'})
      return false
    }
    if (appointment && appointment.is_require_buyer_idcard) {
      if (!(/^\d{17}(\d|X|x)$/.test(identity_num))) {
        Taro.showToast({title: '请正确填写身份证号码', icon: 'none'})
        return false
      }
    }
    let orderNum = 1
    if (this.state.appointment.continuous_type !== 2) {
      orderNum = num
    } else {
      if (this.orderNumRangeType) {
        orderNum = (date.range.length + 1) * num
      }
    }
    if (appointment.goods_type === 2) {
      orderNum = this.state.nights
    }
    if (appointment && appointment.is_require_buyer_idcard) {
      this.setState({identity: true})
    }
    const data = {
      // custom_item_detail:JSON.stringify({
      //   arr:[{linkman: name, phone: phone,identity_num:identity_num}]
      //   ,custom_item_config:{name:true,phone:true,identity_num:identity}
      // }),
      linkman: name,
      phone: phone,
      remark: remarks,
      uuid: this.goodId,
      totalNum: num,
      num: orderNum,
      goodsUuid: curUuid,
      // appointmentDateRange: JSON.stringify({start: '', end: ''}),
      ticketArr: code.join(',')
    }
    if (appointment && appointment.is_require_buyer_idcard) {
      data['identity_num'] = identity_num || ''
    }
    if (this.state.appointment && (this.state.appointment.continuous_type === 2 || (this.state.appointment.continuous_type === 1 && this.state.appointment.goods_type == '2'))) {
      const dateNew = this.deepClone(date)
      dateNew.range = []
      data['appointmentDateRange'] = JSON.stringify(dateNew)
    } else {
      data['appointmentDate'] = date.start
    }
    Taro.showLoading({title: '提交中...'})
    let confirmRet = await http.HPost(APPONINTMENT_CREATE_NEW_ORDER, data)
    if (confirmRet && confirmRet != 999) {
      setTimeout(() => {
        Taro.hideLoading()
      }, 3000)
      if (confirmRet.data && confirmRet.data.pay_info) {
        const info = JSON.parse(confirmRet.data.pay_info)
        confirmRet = {
          timeStamp: info.timeStamp,
          nonceStr: info.nonceStr,
          package: info.package,
          signType: info.signType,
          paySign: info.paySign,
          uuid: confirmRet.data.uuid
        }
        const res = this.state.appointment
        if (res) {
          if (res.pay_type === 1) { //线上支付
            if (this.state.totalPrice > 0) {
              Taro.showLoading({title: '支付中...'})
              if (TARO_ENV === 'h5') {
                await payment.payment(info)
                Taro.hideLoading()
                Taro.showToast({ title: '预约成功!', duration: 2000 })
                setTimeout(()=>{
                  Taro.redirectTo({
                    url: '/other/appointment/detail?itemId=' + confirmRet.uuid
                  });
                },2000)
              } else {
                Taro.requestPayment({
                  timeStamp: confirmRet.timeStamp || '',
                  nonceStr: confirmRet.nonceStr || '',
                  package: confirmRet.package || '',
                  signType: confirmRet.signType || 'MD5',
                  paySign: confirmRet.paySign || '',
                  success: function (data) {
                    Taro.redirectTo({
                      url: '/other/appointment/detail?itemId=' + confirmRet.uuid
                    });
                  },
                  fail: function (data) {
                    Taro.showModal({
                      title: '提示',
                      content: '超时未支付系统将自动取消预约订单，现在去付款？',
                      success: function (res) {
                        if (res.confirm) {
                          Taro.redirectTo({
                            url: '/main/order/order?status=0'
                          })
                        }
                      }
                    });
                  },
                  complete: function () {
                    setTimeout(() => {
                      Taro.hideLoading()
                    }, 3000)
                  }
                })
              }
            }
          }
        }
      } else {
        Taro.showToast({
          title: '预约成功！',
          icon: 'success',
          duration: 2000,
          complete: function () {
            setTimeout(function () {
              Taro.redirectTo({
                url: '/other/appointment/detail?itemId=' + confirmRet.data.uuid
              });
            }, 2000)
          }
        })
      }
      // Taro.showToast({title: '预约成功！'})
      // Taro.redirectTo({url: '/other/appointment/detail?itemId=' + confirmRet.uuid})
    } else {
      setTimeout(() => {
        Taro.hideLoading()
      }, 3000)
      if (confirmRet == 999) {
        this.setState({isOpened: true})
      }
    }
  }

  deepClone(source) {
    const targetObj = source.constructor === Array ? [] : {}
    Object.keys(source).forEach(keys => {
      if (source[keys] && typeof source[keys] === 'object') {
        targetObj[keys] = this.deepClone(source[keys])
      } else {
        targetObj[keys] = source[keys]
      }
    })
    return targetObj
  }

  handleConfirm() {
    if (TARO_ENV === 'h5') {
      window.location.replace(window.location.origin + '/main/order/order')
    } else {
      Taro.redirectTo({
        url: '/main/order/order'
      });
    }
  }

  render() {
    const {loadStatus, isOpened, nights, maxAmount, appointment, products, date, num, code, name, phone, remarks, daysInfo, curUuid, totalNum, identity_num, totalPrice} = this.state
    const _env = Taro.getCurrentInstance().router.params.env;
    return (
      <View className='appoint-order-root'>
        <GzhAuth />
        <AtModal
          className='at-model-dialog'
          isOpened={isOpened}
          title='提示'
          cancelText='取消'
          confirmText='确认'
          onCancel={() => {
            this.setState({isOpened: false})
          }}
          onConfirm={this.handleConfirm}
          content='请先支付之前的订单'
        />
        <View className='wrap1 box no-padding-top' onClick={()=> { Taro.navigateTo({ url: '' }) }}>
          <View className='content' style='padding: 10px !important;'>
            <View className='pro-name'>{appointment && appointment.name || ''}</View>
          </View>
        </View>
        {appointment && (appointment.intro || appointment.note) &&
        <View className='wrap1 box des'>
          {appointment && appointment.intro && <View className='item'>
            <View className='title'>产品描述</View>
            <View className='content'>{appointment && appointment.intro || ''}</View>
          </View>}
          {appointment && appointment.note && <View className='item'>
            <View className='title'>预约提示</View>
            <View className='content'>{appointment && appointment.note || ''}</View>
          </View>}
        </View>
        }
        <View className='wrap1 box product'>
          {/*<View className='title'>预约产品</View>*/}
          <View className='content'>
            {products.length > 0 && products.map(item => <View key={item.uuid} className='radio'
              hoverClass='radio-hover'
              onClick={this.selectProduct.bind(this, item.uuid)}
            >
              <View className='left'>{item.name}{item.bookingEndShow &&
              <View style='font-size:26rpx;'>[{item.bookingEndShow}]</View>}
                {item.refund_rules && <View style='font-size:26rpx;'>{item.refund_rules}</View>}
              </View>
              <View className={`checkbox__input ${item.selected && 'is-checked'}`} ><View className='checkbox__inner' /></View>
            </View>)}
          </View>
        </View>
        {loadStatus !== 'loading' && <Calendar env={_env} data={daysInfo} mode='callback' goodsType={appointment.goods_type}
          lateNum={appointment.late_num}
          goodId={this.goodId}
          goodsId={curUuid}
          continuousType={appointment && appointment.continuous_type}
          type={appointment && appointment.continuous_type === 2 ? 'range' : appointment.goods_type === 2 ? 'range' : 'single'}
          onConfirm={this.calendarConfirm.bind(this)}
        />}
        <View className='wrap1 box'>
          {/*<View className='title'>预约时间</View>*/}
          <View className='content'>
            {appointment && appointment.goods_type !== 2 &&
            <View className='content-left'>
              <View>选择日期：</View>
              <View>{date.start}{appointment.continuous_type === 2 && date.end &&
              <Text className='date-end'> 至 {date.end}</Text>}</View>
            </View>
            }
            {appointment && appointment.goods_type === 2 &&
            <View className='content-left'>
              <View>{date.start} 至 {date.end}</View>
              <View className='content-right' style='color: #000;'>共{nights}晚</View>
            </View>}
          </View>
        </View>
        <View className='wrap1 box'>
          {/*<View className='title'>{appointment && appointment.goods_type !== 2 ? '预约数量:' : '预约间数:'}</View>*/}
          <View className='content'>
            <View>{appointment && appointment.goods_type !== 2 ? '数量:' : '间数:'}</View>
            <AtInputNumber type='number' min={0} onBlur={this.iosScroll.bind(this)} max={this.orderUUID ? maxAmount : 9999} step={1} value={num} onChange={(value) => {this.setState({num: value}, () => {this.numChange(this.state.num * this.state.dateNum)})}} />
          </View>
        </View>
        <View className='wrap1 box'>
          <View className='title'>券号(预约码)</View>
          {code.length > 0 && code.map((item, index) => <View className='content'>
            <View className='left'>券码：</View>
            <View className='right'><Input type='text' onBlur={this.iosScroll.bind(this)} placeholder='请填写正确的券号(预约码)'
              value={item}
              onInput={this.codeInput.bind(this, index)}
            /></View>
          </View>)}
        </View>
        <View className='wrap1 box'>
          <View className='title'>客人信息</View>
          <View className='content'>
            <View className='left'>姓名：</View>
            <View className='right'><Input type='text' onBlur={this.iosScroll.bind(this)} value={name} maxLength={15} onInput={(value) => {this.setState({name: value.detail.value})}} /></View>
          </View>
          <View className='content'>
            <View className='left'>电话：</View>
            <View className='right'><Input type='text' onBlur={this.iosScroll.bind(this)} value={phone} onInput={(value) => {this.setState({phone: value.detail.value})}} /></View>
          </View>
          {!!appointment && !!appointment.is_require_buyer_idcard && <View className='content'>
            <View className='left'>身份证：</View>
            <View className='right'><Input type='idcard' onBlur={this.iosScroll.bind(this)} value={identity_num} onInput={(value) => {this.setState({identity_num: value.detail.value})}} /></View>
          </View>}
        </View>
        <View className='wrap1 box'>
          <View className='title'>备注</View>
          <View className='content'>
            <View className='block'>
              <AtTextarea value={remarks} onBlur={this.iosScroll.bind(this)} onChange={(value) => {this.setState({remarks: value})}} />
            </View>
          </View>
        </View>
        <View className='foot'>
          <View className='tips'>应付{(appointment && appointment.pay_type === 1) ? "在线补差价¥" + totalPrice : "线下补差价¥" + totalPrice}元</View><View className={`btn ${this.btnDisabled && 'btn-disabled'}`} onClick={this.confirm.bind(this)}>确认预约</View>
        </View>
      </View>
    )
  }
}
